package threads;

import java.util.LinkedList;
import java.util.UUID;

public class ProducerConsumer {

    private LinkedList<String> queue = new LinkedList<>();
    private static final int cap = 10;


    public synchronized void add() {
        if (queue.size() == cap) {
            await(0);
        }
        this.notifyAll();
        queue.add(UUID.randomUUID().toString());
    }

    public synchronized String fetch() {
        if (queue.size() == 0) {
            await(10000L);
        }
        if (queue.size() == 0) return null;
        String e = queue.removeLast();
        this.notify();
        return e;
    }

    public void await(long n) {
        try {
            this.wait(n);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ProducerConsumer pc = new ProducerConsumer();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                try {
                    Thread.sleep(10L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                pc.add();
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(10L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                pc.add();
            }
        });
        Thread t3 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                try {
                    Thread.sleep(10L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(pc.fetch());
            }
        });
        t1.start();
        t2.start();
        t3.start();

    }
}
